#include "cppinc/dac81416.h"
#include "bsp.h"

struct DataFrameDac81416 {
    // first byte
    uint32_t CMD  :4;
    uint32_t RW   :1;
    uint32_t DNC  :3;
    // second byte
    uint32_t DM4  :4;
    uint32_t CH   :4;
    // thrid byte
    uint32_t D8   :8;
    // forth byte
    uint32_t MODE :4;
    uint32_t DL4  :4;
} dac81416Data_t;

uint8_t Dac81416ChToBin[5] = {0x00, 0x01, 0x02, 0x03, 0x0F};

void DrvDac81416::Init()
{
    BspGpioSet(m_io.load, GPIO_CLR);
    BspGpioSet(m_io.clr, GPIO_CLR);
    for (uint8_t ch = CHNL_1; ch <= CHNL_16; ch++) {
        SetDacDataBuffer(ch, 0);
    }
    BspGpioSet(m_io.clr, GPIO_SET);
    BspGpioSet(m_io.load, GPIO_SET);
}

void DrvDac81416::SetDacDataBuffer(uint32_t ch, uint16_t dacData)
{
    if (ch > CHNL_16) {
        return;
    }
    DataFrameDac81416 frame;
    frame.CH = Dac81416ChToBin[ch];
    frame.DM4 = dacData >> 12;
    frame.D8 = dacData >> 4;
    frame.DL4 = dacData & 0xf;
    // spi transmit
    BspGpioSet(m_io.cs, GPIO_CLR);
    BspDatabusWrite(m_dataBus, (uint8_t*)&frame, 4);
    BspGpioSet(m_io.cs, GPIO_SET);
}

void DrvDac81416::LoadVoltage()
{
    // load voltage output
    BspGpioSet(m_io.load, GPIO_CLR);
    BspGpioSet(m_io.load, GPIO_SET);
}

